package com.atguigu.tingshu.user.api;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.atguigu.tingshu.account.client.UserAccountFeignClient;
import com.atguigu.tingshu.common.constant.KafkaConstant;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.login.GuiGuLogin;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.service.KafkaService;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.seata.spring.annotation.GlobalTransactional;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Tag(name = "微信授权登录接口")
@RestController
@RequestMapping("/api/user/wxLogin")
@Slf4j
public class WxLoginApiController {

    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private KafkaService kafkaService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserAccountFeignClient userAccountFeignClient;

    /**
     * 模拟用户登录创建多个对象
     * @param userId
     * @return
     */
    @Operation(summary = "手动获取token")
    @GetMapping("/getToken/{userId}")
    public Result login(@PathVariable Long userId) {
        //	获取用户信息 , 数据库中还需要有一条信息. 25 24
        UserInfo userInfo = userInfoService.getById(userId);
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        //  将用户信息存储到redis中.
        redisTemplate.opsForValue().set(RedisConstant.USER_LOGIN_KEY_PREFIX+token, userInfo, RedisConstant.USER_LOGIN_REFRESH_KEY_TIMEOUT, TimeUnit.SECONDS);
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        return Result.ok(map);
    }

    //  http://127.0.0.1/api/user/wxLogin/wxLogin/0e15ohll2JVJsc40Dtol2UVb4w35ohlY
    @Operation(summary = "小程序授权登录")
    @GetMapping("/wxLogin/{code}")
    @GlobalTransactional
    public Result wxLogin(@PathVariable String code){
        /*
          1. 根据code 来获取 OpenId  odo3j4uWeUuI_1EpmncOny-qMFyY
          2. 使用OpenId 查询用户信息
                true:
                    说明用户注册
                false:
                    说明用户未注册 -- 进行注册 insert into user_info;
          3. 生成一个token 存储起来
          4. 将用户信息存储到缓存
         */
        //  传入自己的appid key
        WxMaJscode2SessionResult sessionResult = null;
        try {
            sessionResult = wxMaService.getUserService().getSessionInfo(code);
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
        String openId = sessionResult.getOpenid();
        System.out.println("openId:\t"+openId);

        //  select * from user_info where wx_open_id = ?;
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getWxOpenId,openId);
        UserInfo userInfo = userInfoService.getOne(wrapper);
        //  判断userInfo
        if (null == userInfo){
            //  说明当前这个微信用户不存在user_info 表中. 注册!
            userInfo = new UserInfo();
            userInfo.setWxOpenId(openId);
            userInfo.setNickname("听友:"+System.currentTimeMillis());
            //  表示非vip
            userInfo.setIsVip(0);
            userInfo.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
            //  注册成功
            userInfoService.save(userInfo);
            //  初始化一个账户信息: 同步/作异步操作 同步分布式事务：seata user - account
            //  发送topics , 发生的内容
            //  kafkaService.sendMsg(KafkaConstant.QUEUE_USER_REGISTER,userInfo.getId().toString());
            Result result = userAccountFeignClient.initUserAccount(userInfo.getId());
            if (result.getCode()!=200){
                throw new RuntimeException();
            }
            //  异常信息：
            //  int i = 1/0;
        }
        //  说明当前这个微信用户存在user_info 表中！
        String token = UUID.randomUUID().toString().replaceAll("-","");
        //  创建map 集合来存储token 数据
        HashMap<String, Object> map = new HashMap<>();
        map.put("token",token);
        //  存储到缓存中：redis：String数据类型：
        String userLoginKey = RedisConstant.USER_LOGIN_KEY_PREFIX+token;
        redisTemplate.opsForValue().set(userLoginKey,userInfo,RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);

        //  默认返回
        return Result.ok(map);
    }

    /**
     * 根据用户Id获取到用户数据
     * @return
     */
    @GuiGuLogin
    @Operation(summary = "获取登录信息")
    @GetMapping("getUserInfo")
    public Result getUserInfo(){
        //  根据用户Id获取数据
        Long userId = AuthContextHolder.getUserId();
        //  调用服务层方法.
        UserInfoVo userInfoVo = this.userInfoService.getUserInfoById(userId);
        //  返回数据
        return Result.ok(userInfoVo);
    }

    /**
     * 更新用户信息
     * @param userInfoVo
     * @return
     */
    @GuiGuLogin
    @Operation(summary = "更新用户信息")
    @PostMapping("/updateUser")
    public Result updateUser(@RequestBody UserInfoVo userInfoVo){
        //  知道当前用户Id 是谁！
        Long userId = AuthContextHolder.getUserId();
        //  创建用户对象
        UserInfo userInfo = new UserInfo();
        userInfo.setId(userId);
        userInfo.setNickname(userInfoVo.getNickname());
        userInfo.setAvatarUrl(userInfoVo.getAvatarUrl());
        //  更新用户信息
        userInfoService.updateById(userInfo);
        return Result.ok();
    }

}
